package net.solvetheriddle.wwclient.activity;

import java.io.IOException;

import net.solvetheriddle.wwclient.WWLogic;
import net.solvetheriddle.wwclient.R;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

/**
 * @author anoniim
 * 
 */
public class LoginActivity extends Activity {

  private static final String PREF_COMPANY = "PREF_COMPANY";
  private static final String PREF_USERNAME = "PREF_USERNAME";
  private static final String PREF_PASS = "PREF_PASS";
  private static final String PREF_REMEMBER = "PREF_REMEMBER";

  private static final int LOGIN_COMPANY = 0;
  private static final int LOGIN_USERNAME = 1;
  private static final int LOGIN_PASSWORD = 2;
  // UI widgets
  private EditText usernameET;
  private EditText companyET;
  private EditText passET;
  private Button loginButton;
  private TextView errorTV;
  private CheckBox rememberCB;
  private ProgressBar loginProgressBar;
  // logic handling fields
  private SharedPreferences settings;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    try {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.login); // set layout (.xml file)

      initPreferences();
      setupViews();
      addButtonListener();

    } catch (Exception e) {
      // Log exception with the WWCLIENT tag
      Log.e("WWCLIENT", "! ERROR IN CODE: " + e.toString());
      e.printStackTrace();
    }
  }

  @Override
  protected void onStart() {
    super.onStart();

    loadLoginKeysFromPreferences();
  }

  @Override
  protected void onPause() {
    super.onPause();

    saveLoginKeysToPreferences();
  }

  /**
   * get the activity preferences object
   */
  private void initPreferences() {
    settings = getPreferences(Activity.MODE_PRIVATE);
  }

  private void saveLoginKeysToPreferences() {
    // edit preferences
    SharedPreferences.Editor editor = settings.edit();
    if (rememberCB.isChecked()) {
      // save the UI state
      editor.putString(PREF_COMPANY, companyET.getText().toString());
      editor.putString(PREF_USERNAME, usernameET.getText().toString());
      editor.putString(PREF_PASS, passET.getText().toString());
      editor.putBoolean(PREF_REMEMBER, rememberCB.isChecked());
      editor.commit();
    } else {
      // clear preferences if the user does not want to save them
      editor.putString(PREF_COMPANY, null);
      editor.putString(PREF_USERNAME, null);
      editor.putString(PREF_PASS, null);
      editor.putBoolean(PREF_REMEMBER, false);
      editor.commit();
    }
  }

  private void loadLoginKeysFromPreferences() {
    // load preferences
    String company = settings.getString(PREF_COMPANY, "");
    String username = settings.getString(PREF_USERNAME, "");
    String password = settings.getString(PREF_PASS, "");
    boolean remember = settings.getBoolean(PREF_REMEMBER, false);
    // update UI
    companyET.setText(company);
    usernameET.setText(username);
    passET.setText(password);
    rememberCB.setChecked(remember);
  }

  /**
   * manage Login Button
   */
  private void addButtonListener() {
    loginButton.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        String username = usernameET.getText().toString();
        String company = companyET.getText().toString();
        String pass = passET.getText().toString();
        errorTV.setText("");

        // check login in the background
        new LoginTask().execute(company, username, pass);
      }
    });
  }

  /**
   * Get reference to UI widgets
   */
  private void setupViews() {
    usernameET = (EditText) findViewById(R.id.usernameEditText);
    companyET = (EditText) findViewById(R.id.companyEditText);
    passET = (EditText) findViewById(R.id.passEditText);
    loginButton = (Button) findViewById(R.id.loginButton);
    errorTV = (TextView) findViewById(R.id.errorTextView);
    rememberCB = (CheckBox) findViewById(R.id.rememberCheckBox);
    loginProgressBar = (ProgressBar) findViewById(R.id.login_progress_bar);
  }

  private class LoginTask extends AsyncTask<String, Void, Integer> {

    private static final int LOGIN_FAILED_IO = -1;
    private static final int LOGIN_INCORRECT = 0;
    private static final int LOGIN_CORRECT = 1;

    // Load resources from UI Thread to this Asynchronous Task
    @Override
    protected void onPreExecute() {
      super.onPreExecute();

      loginProgressBar.setVisibility(ProgressBar.VISIBLE);
      loginButton.setClickable(false);
    }

    // Run this code in background. Do not reference UI Thread here!
    @Override
    protected Integer doInBackground(String... loginKeys) {
      String company = loginKeys[LOGIN_COMPANY];
      String username = loginKeys[LOGIN_USERNAME];
      String password = loginKeys[LOGIN_PASSWORD];

      try {
        // check login (time consuming operation)
        if (WWLogic.loginUser(company, username, password) != null) {
          return LOGIN_CORRECT;
        }
      } catch (IOException e) {
        e.printStackTrace();
        return LOGIN_FAILED_IO;
      }
      // login incorrect
      return LOGIN_INCORRECT;
    }

    // Update UI according to result from doInBackground() method
    @Override
    protected void onPostExecute(Integer result) {
      switch (result) {
      case LOGIN_CORRECT:
        Intent mainActivity = new Intent(loginButton.getContext(), MainActivity.class);
        finish();
        startActivity(mainActivity);
        break;
      case LOGIN_INCORRECT:
        loginProgressBar.setVisibility(ProgressBar.INVISIBLE);
        loginButton.setClickable(true);
        if (errorTV.getText().equals("")) {
          // error label does not contain any previous message
          errorTV.setText(R.string.loginIncorrect);
          passET.setText("");
        }
        break;
      case LOGIN_FAILED_IO:
        loginProgressBar.setVisibility(ProgressBar.INVISIBLE);
        loginButton.setClickable(true);
        errorTV.setText(R.string.serverError);
        break;
      default:
        loginProgressBar.setVisibility(ProgressBar.INVISIBLE);
        loginButton.setClickable(true);
        errorTV.setText(R.string.unknownError);
        break;
      }
      super.onPostExecute(result);
    }
  }
}